package com.yjq.test;

import com.yjq.test.pojo.Evection;
import org.activiti.engine.*;
import org.activiti.engine.impl.RuntimeServiceImpl;
import org.activiti.engine.impl.TaskServiceImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;

public class BusinessKeyDemo {
    /**
     * 给流程实例添加业务关键字
     */
    @Test
    public void addBusinessKey(){
        //1、得到流程引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        //2、获取RuntimeService
        RuntimeService runtimeService=processEngine.getRuntimeService();
        //3、根据流程定义id启动流程
        ProcessInstance processInstance=runtimeService.startProcessInstanceByKey("myLeave","1001");
        // 输出内容
        System.out.println("流程定义id："+processInstance.getProcessDefinitionId());
        System.out.println("流程实例id:"+processInstance.getId());
        System.out.println("当前活动id："+processInstance.getActivityId());
    }

    /**
     * 完成一个带有业务关键字的流程任务
     */
    @Test
    public void finishByBusinessKey(){
        // 获取引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        // 获取taskService
        TaskService taskService=processEngine.getTaskService();

        //根据流程key，任务的负责人 查询任务
        // 返回一个任务对象
        Task task=taskService.createTaskQuery()
                .processDefinitionKey("myLeave")//流程key
                .processInstanceBusinessKey("1001")
                .taskAssignee("manager")//要查询的负责人
                .singleResult();
        // =====在这个过程中完成相应的逻辑业务处理======

        // 完成任务，参数，任务id
        taskService.complete(task.getId());
    }

    /**
     * 根据流程定义的关键字挂起和激活流程
     * 这个方法是将和这个流程定义关键字下所有的流程实例挂起
     */
    @Test
    public void suspendProcessDefinition(){
        // 获取引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        // 获取taskService
        RepositoryService repositoryService=processEngine.getRepositoryService();
        ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("myLeave")
                .singleResult();

        //遍历这个集合，得到任务信息
            if (processDefinition.isSuspended()){
                repositoryService.activateProcessDefinitionById(processDefinition.getId(),true,null);
                System.out.println("流程定义id:"+processDefinition.getId()+",已激活");
            }
            else{
                repositoryService.suspendProcessDefinitionById(processDefinition.getId(),true,null);
                System.out.println("流程定义id:"+processDefinition.getId()+",已挂起");
            }
    }

    /**
     * 根据流程实例的id将任务挂起、激活
     * 这个方法只针对对应id的流程实例
     */
    @Test
    public void suspendProcessInstance(){
        // 获取引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        //获取RuntimeService
        RuntimeService runtimeService=processEngine.getRuntimeService();
        //创建查询根据条件查询对应的流程实例
        ProcessInstance processInstance=runtimeService.createProcessInstanceQuery()
                .processInstanceId("70001")
                .singleResult();

        if (processInstance.isSuspended()){
            runtimeService.activateProcessInstanceById(processInstance.getId());
            System.out.println("流程实例id:"+processInstance.getId()+",已激活");
        }
        else{
            runtimeService.suspendProcessInstanceById(processInstance.getId());
            System.out.println("流程实例id:"+processInstance.getId()+",已挂起");
        }
    }

    /**
     * 部署新建的请假审批流程定义
     */
    @Test
    public void evectionDeploy(){
//        首先获取流程引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        // 获取流程仓库服务
        RepositoryService repositoryService=processEngine.getRepositoryService();
        // 根据流程定义文件的class Path地址开始部署
        Deployment deployment= repositoryService.createDeployment()
                .addClasspathResource("bpmn/evection.bpmn")
                .addClasspathResource("bpmn/evection.png")
                .name("公司最新请假审批流程")
                .deploy();

        //输出部署的流程定义信息
        System.out.println("流程定义id:"+deployment.getId());
        System.out.println("流程定义名称："+deployment.getName());
    }

    /**
     * 根据最新的流程定义，创建流程实例
     * 大于三天的请假流程
     */
    @Test
    public void crateProcessInstance(){
        //        首先获取流程引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        // 首先得到流程仓储服务RuntimeService
        RuntimeService runtimeService=processEngine.getRuntimeService();
        //定义流程变量
        Map<String,Object> obj=new ConcurrentHashMap<>();
        obj.put("worker","张三");
        obj.put("manager","王经理");
        obj.put("finacer","李姐");
        obj.put("totalManager","刘总");

        //录入需要请假的天数进行过程判断
        Evection evection=new Evection();
        evection.setNum(3);
        obj.put("evection",evection);
        //得到对应的流程定义
        ProcessInstance processInstance= runtimeService.startProcessInstanceByKey("evection",obj);

        //将开启的流程实例信息输出
        System.out.println("流程实例id:"+processInstance.getId());
        System.out.println("流程定义id:"+processInstance.getProcessDefinitionId());
        System.out.println("当前活动id:"+processInstance.getActivityId());
    }



    /**
     * 根据最新的流程定义，创建流程实例
     * 小于三天的请假流程
     */
    @Test
    public void crateProcessInstance1(){
        //        首先获取流程引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        // 首先得到流程仓储服务RuntimeService
        RuntimeService runtimeService=processEngine.getRuntimeService();
        //定义流程变量
        Map<String,Object> obj=new ConcurrentHashMap<>();
        obj.put("worker","张三1");
        obj.put("manager","王经理1");
        obj.put("finacer","李姐1");
        obj.put("totalManager","刘总1");

        //录入需要请假的天数进行过程判断
        Evection evection=new Evection();
        evection.setNum(2);
        obj.put("evection",evection);
        //得到对应的流程定义
        ProcessInstance processInstance= runtimeService.startProcessInstanceByKey("evection",obj);

        //将开启的流程实例信息输出
        System.out.println("流程实例id:"+processInstance.getId());
        System.out.println("流程定义id:"+processInstance.getProcessDefinitionId());
        System.out.println("当前活动id:"+processInstance.getActivityId());
    }




    /**
     * 查询所有该流程实例下的任务
     */
    @Test
    public void queryTask(){
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        //定义一个流程实例变量，根据这个流程实例id得到所有该实例下的待处理任务
        String processInstanceId="110001";
        String processDefinitionKey="evection";
        //新建taskService
        TaskService taskService=processEngine.getTaskService();
        List<Task> tasks=taskService.createTaskQuery()
//                .processInstanceId(processInstanceId)
                .processDefinitionKey(processDefinitionKey)
                .list();
        //遍历得到的结果
        for (Task task : tasks) {
            System.out.println("流程实例id："+task.getProcessInstanceId());
            System.out.println("流程负责人："+task.getAssignee());
            System.out.println("任务id:"+task.getId());
            System.out.println("任务名称："+task.getName());
        }
    }


    /**
     * 修改流程变量
     */
    @Test
    public void complete2(){
        //指定任务负责人
        String assignee="王经理1";
        //获取流程引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        //获取taskService
        TaskService taskService=processEngine.getTaskService();
        //根据流程定义的id和负责人查询任务
        Task task=taskService.createTaskQuery()
                .processDefinitionKey("evection")
                .taskAssignee(assignee)
                .singleResult();
        //重新指定流程负责人
        taskService.setVariable(task.getId(),"finacer","roy");
        //完成任务
        taskService.complete(task.getId());
    }


    /**
     * 完成任务
     */
    @Test
    public void complete(){
        //指定任务负责人
        String assignee="roy";
        //获取流程引擎
        ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
        //获取taskService
        TaskService taskService=processEngine.getTaskService();
        //根据流程定义的id和负责人查询任务
        Task task=taskService.createTaskQuery()
                .processDefinitionKey("evection")
                .taskAssignee(assignee)
                .singleResult();
        //完成任务
        taskService.complete(task.getId());
    }
}
